#ifndef FTPSESSIONWORKER_H
#define FTPSESSIONWORKER_H

#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>
#include "serverconfig.h"

class FtpCommand
{
public:
    FtpCommand() = default;
    FtpCommand(const QByteArray& byteArray);

    QByteArray cmd() const;
    QByteArray arg() const;

    QString data() const;
    void setData(const QString &data);

    bool isNull() const;
    void setNull();

private:
    QByteArray m_cmd;
    QByteArray m_arg;
    QString    m_data;
};

class FtpSessionWorker : public QObject
{
    Q_OBJECT
public:
    explicit FtpSessionWorker(qintptr socketDescriptor, const ServerConfig& serverConfig,
                         QObject *parent = nullptr);
    ~FtpSessionWorker();

signals:
    void quit();

public slots:
    void init();
    void clean();
    void onReadyRead();
    void onError(QAbstractSocket::SocketError error);
    void onDisconnected();
    void startNextCommand();

private:
    void handleUSER();
    void handlePASS();
    void handleFEAT();
    void handleOPTS();
    void handlePORT();
    void handlePASV();
    void handleTYPE();
    void handleSTRU();
    void handleMODE();
    void handleCWD();
    void handleCDUP();
    void handleQUIT();
    void handleDELE();
    void handleRMD();
    void handleMKD();
    void handlePWD();
    void handleRNFR();
    void handleRNTO();
    void handleLIST(bool detail = true);
    void handleNLST();
    void handleRETR();
    void handleSTOR();
    void handleSTOU();
    void handleAPPE();
    void handleALLO();
    void handleREST();
    void handleABOR();
    void handleSYST();
    void handleSTAT();
    void handleHELP();

    QString resolvePathName(const QString &pathName);
    QString pathFromRoot(const QString &pathName);
    QString getListData(const QString &path, bool detail);
    bool isInRootDir(const QString &path);

private:
    qintptr      m_socketDescriptor;
    ServerConfig m_serverConfig;
    QTcpSocket  *m_cmdSocket = nullptr;   // 传送命令
    QTcpSocket  *m_dataSocket = nullptr;  // 传送数据
    QTcpServer  *m_dataServer = nullptr;  // 被动模式下负责监听连接请求
    QList<FtpCommand> m_commandQueue;
    FtpCommand   m_currentCommand;
    FtpCommand   m_lastCommand;
    bool         m_isAnonymous = false;
    bool         m_isAsciiMode = true;
    QString      m_currentDir = "/";      // 当前目录
    qint64       m_restartPos = 0;
};


#endif // FTPSESSIONWORKER_H
